﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Excel;
using Zzva.Report;
using System.Reflection;
using Zzva.Common;



namespace Zzva.ReportExcel
{

    
    public class TReportExcel:TReportBase 
    {




        private void ScanListReportMen(System.Collections.IList pDokument, TOneTableExcel pOneTableExcel,
                                      EReportFieldView pReportFieldView)
        {
            try
            {

                Type lTypeItem;
                PropertyInfo[] lPropertyInfo;
                string lFieldObozn;
                string lFieldOboznFull;
                Type lTypeProperty;
                bool lPropertyIsClass;
                bool lPropertyIsPrimitive;
                bool lPropertyIsValueType;
                string lPropertyObozn;
                object lFieldValue;


                foreach (object lItem in pDokument)
                {

                    lTypeItem = lItem.GetType();
                    lPropertyInfo = lTypeItem.GetProperties();

                    for (int i = 0; i < lPropertyInfo.Length; i++)
                    {
                        lFieldObozn = lPropertyInfo[i].Name;
                        lFieldOboznFull = "Report." + lFieldObozn;
                        lTypeProperty = lPropertyInfo[i].PropertyType;
                        lPropertyIsClass = lTypeProperty.IsClass;
                        lPropertyIsPrimitive = lTypeProperty.IsPrimitive;
                        lPropertyIsValueType = lTypeProperty.IsValueType;
                        lPropertyObozn = lTypeProperty.Name;

                        if ((lPropertyIsClass == true) & (lPropertyObozn != "String"))//здесь вызываем рекрусивно себя
                        {

                            lFieldValue = lTypeItem.InvokeMember(lFieldObozn,
                                          BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty,
                                          null, lItem, null);




                            switch (pReportFieldView)
                            {
                                case EReportFieldView.ExpandAsObject :
                                    ScanReportFieldEntity(lFieldValue, pOneTableExcel, lFieldOboznFull);
                                    break;
                                case EReportFieldView.ViewAsString :
                                    pOneTableExcel.SetValue(lFieldOboznFull, lFieldValue.ToString());
                                    break;
                                default:
                                    ////break;
                                    throw (new CommonException("Нет константы для EReportFieldView")); 
                            }

                                






                        }
                        else if ((lPropertyIsPrimitive = true) & (lPropertyIsValueType = true) | (lPropertyObozn == "String"))   //здесь присваиваеим значения                  
                        {
                            lFieldValue = lTypeItem.InvokeMember(lFieldObozn,
                                          BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty,
                                          null, lItem, null);

                            pOneTableExcel.SetValue(lFieldOboznFull, lFieldValue);
                        }

                        else { throw (new CommonException("Нет типа у свойства")); }

                    }

                    pOneTableExcel.NewLine();
                }
            }
            catch (Exception e1) { throw e1; }
            finally { }
        }


        protected override void CreateReport(System.Collections.IList pDokument, EReportFieldView pReportFieldView)
        {
            try
            {

                if (pDokument.Count == 0) { throw (new CommonException("Документ пустой")); }

                Excel.ApplicationClass lExcel;
                lExcel = GetExcel();

                Excel.Workbook lWkb;
                lWkb = lExcel.Workbooks.Add(1);

                Type lTypeItem;
                object lItem;
                PropertyInfo[] myPropertyInfo;
                string lFildObozn;
                lFildObozn = "";

                lItem = pDokument[0];
                lTypeItem = lItem.GetType();
                myPropertyInfo = lTypeItem.GetProperties();

                for (int i = 0; i < myPropertyInfo.Length; i++)
                {
                    lFildObozn = myPropertyInfo[i].Name;
                }


                TReportListField lReportListField = GetReportListField(lItem, "", pReportFieldView);
                TReportFieldEntity lReportFieldEntity = GetReportFieldEntity(lItem, "Report", pReportFieldView);

                int lColLevel = lReportFieldEntity.GetColLevel();
                int lColFieldValue = lReportFieldEntity.GetColFieldValue();
                TReportFieldBase lReportFieldBase = lReportFieldEntity.GetField("Report");

                lExcel.Visible = true;


                Excel.Worksheet lSht;
                lSht = (Excel.Worksheet)lWkb.Worksheets[1];
                TOneTableExcel lOneTableExcel = new TOneTableExcel(lSht, lReportFieldEntity);

                lOneTableExcel.Title = Title;

                ////ScanListReportMen(pDokument, lOneTableExcel);
                ScanListReportMen(pDokument, lOneTableExcel,pReportFieldView);

            }

            catch (Exception e1) { throw e1; }
            finally { }
        }

































































































        private void ScanReportFieldEntity(object pFieldEntity, TOneTableExcel pOneTableExcel,
                                           string pFieldOboznFullParent)
        {
            try
            {

                Type lTypeItem;
                PropertyInfo[] lPropertyInfo;
                string lFieldObozn;
                string lFieldOboznFull;
                Type lTypeProperty;
                bool lPropertyIsClass;
                bool lPropertyIsPrimitive;
                bool lPropertyIsValueType;
                string lPropertyObozn;
                object lFieldValue;


                    lTypeItem = pFieldEntity.GetType();
                    lPropertyInfo = lTypeItem.GetProperties();

                    for (int i = 0; i < lPropertyInfo.Length; i++)
                    {
                        lFieldObozn = lPropertyInfo[i].Name;
                        lFieldOboznFull = pFieldOboznFullParent + "." + lFieldObozn;
                        lTypeProperty = lPropertyInfo[i].PropertyType;
                        lPropertyIsClass = lTypeProperty.IsClass;
                        lPropertyIsPrimitive = lTypeProperty.IsPrimitive;
                        lPropertyIsValueType = lTypeProperty.IsValueType;
                        lPropertyObozn = lTypeProperty.Name;

                        if ((lPropertyIsClass == true) & (lPropertyObozn != "String"))//здесь вызываем рекрусивно себя
                        {
                            lFieldValue = lTypeItem.InvokeMember(lFieldObozn,
                                          BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty,
                                          null, pFieldEntity, null);

                            ScanReportFieldEntity(lFieldValue, pOneTableExcel, lFieldOboznFull);

                        }
                        else if ((lPropertyIsPrimitive = true) & (lPropertyIsValueType = true) | (lPropertyObozn == "String"))   //здесь присваиваеим значения                  
                        {
                            lFieldValue = lTypeItem.InvokeMember(lFieldObozn,
                                          BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty,
                                          null, pFieldEntity, null);

                            pOneTableExcel.SetValue(lFieldOboznFull, lFieldValue);
                        }

                        else { throw (new CommonException("Нет типа у свойства")); }

                    }

            }
            catch (Exception e1) { throw e1; }
            finally { }
        }





        private void ScanListReportMen(System.Collections.IList pDokument, TOneTableExcel pOneTableExcel)
        {
            try
            {

                Type lTypeItem;
                PropertyInfo[] lPropertyInfo;
                string lFieldObozn;
                string lFieldOboznFull;
                Type lTypeProperty;
                bool lPropertyIsClass;
                bool lPropertyIsPrimitive;
                bool lPropertyIsValueType;
                string lPropertyObozn;
                object  lFieldValue;


                foreach (object lItem in pDokument)
                {

                    lTypeItem = lItem.GetType();
                    lPropertyInfo = lTypeItem.GetProperties();

                    for (int i = 0; i < lPropertyInfo.Length; i++)
                    {
                        lFieldObozn = lPropertyInfo[i].Name;
                        lFieldOboznFull = "Report." + lFieldObozn;
                        lTypeProperty = lPropertyInfo[i].PropertyType;
                        lPropertyIsClass = lTypeProperty.IsClass;
                        lPropertyIsPrimitive = lTypeProperty.IsPrimitive;
                        lPropertyIsValueType = lTypeProperty.IsValueType;
                        lPropertyObozn = lTypeProperty.Name;

                        if ((lPropertyIsClass == true) & (lPropertyObozn != "String"))//здесь вызываем рекрусивно себя
                        {
                            
                            lFieldValue = lTypeItem.InvokeMember(lFieldObozn,
                                          BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty,
                                          null, lItem, null);

                            ScanReportFieldEntity(lFieldValue, pOneTableExcel, lFieldOboznFull);

                        }
                        else if ((lPropertyIsPrimitive = true) & (lPropertyIsValueType = true) | (lPropertyObozn == "String"))   //здесь присваиваеим значения                  
                        {
                            lFieldValue = lTypeItem.InvokeMember(lFieldObozn,
                                          BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty,
                                          null, lItem, null);

                            pOneTableExcel.SetValue(lFieldOboznFull, lFieldValue);
                        }

                        else { throw (new CommonException("Нет типа у свойства")); }

                    }

                    pOneTableExcel.NewLine();
                }
            }
            catch (Exception e1) { throw e1; }
            finally { }
        }








        protected override void CreateReport(System.Collections.IList pDokument)
        {
            try
            {


                if (pDokument.Count == 0) { throw (new CommonException("Документ пустой")); }

                Excel.ApplicationClass lExcel;
                lExcel = GetExcel();

                Excel.Workbook lWkb;

                lWkb = lExcel.Workbooks.Add(1);



               Type lTypeItem;
               object lItem;
               PropertyInfo[] myPropertyInfo;
               string lFildObozn;
               lFildObozn = "";

               lItem = pDokument[0];
               lTypeItem = lItem.GetType();
               myPropertyInfo = lTypeItem.GetProperties();

               for (int i = 0; i < myPropertyInfo.Length; i++)
               {
                   lFildObozn = myPropertyInfo[i].Name;
               }



               TReportListField lReportListField = GetReportListField(lItem,"");

               TReportFieldEntity lReportFieldEntity = GetReportFieldEntity(lItem, "Report");

               int lColLevel = lReportFieldEntity.GetColLevel();

               int lColFieldValue = lReportFieldEntity.GetColFieldValue();


               TReportFieldBase lReportFieldBase = lReportFieldEntity.GetField("Report");



               lExcel.Visible = true;



               Excel.Worksheet lSht;
               lSht = (Excel.Worksheet)lWkb.Worksheets[1];
               TOneTableExcel lOneTableExcel = new TOneTableExcel(lSht, lReportFieldEntity);
               ////lOneTableExcel.DrawTitleTable(lSht, lReportFieldEntity, 2, 3);
               ////lOneTableExcel.DrawFrame(lSht, lReportFieldEntity); 

               lOneTableExcel.Title = Title; 


               ScanListReportMen(pDokument, lOneTableExcel); 
               

             
            }

            catch (Exception e1) { throw e1; }
            finally { }
        }



        public Excel.ApplicationClass GetExcel()
        {
            try
            {
                Excel.ApplicationClass lExcel;
                lExcel = new ApplicationClass();
                return lExcel;
            }
            catch (Exception e1) { throw e1; }
            finally { }
        }



        public TReportExcel()
            : base()
        {
        }






 







    }
}
